package drds.common.db.xml_mapping.io;

import java.io.InputStream;


public class ClassLoaderWrapper {


  ClassLoader systemClassLoader;

  ClassLoaderWrapper() {
    try {
      systemClassLoader = ClassLoader.getSystemClassLoader();
    } catch (SecurityException ignored) {
      // AccessControlException on Google App Engine
    }
  }


  /**
   * Find a class on the classpath (or die trying)
   *
   * @param name - the class to look for
   * @return - the class
   * @throws ClassNotFoundException Duh.
   */
  public Class<?> classForName(String name) throws ClassNotFoundException {
    return classForName(name, Thread.currentThread().getContextClassLoader());
  }


  /**
   * Try to get a resource from a group of classloaders
   *
   * @param resource    - the resource to get
   * @param classLoader - the classloaders to examine
   * @return the resource or null
   */
  InputStream getResourceAsStream(String resource, ClassLoader classLoader) {
    if (null != classLoader) {

      // try to find the resource as passed
      InputStream inputStream = classLoader.getResourceAsStream(resource);

      // now, some class loaders want this leading "/", so we'll add it and try again if we didn't find the resource
      if (null == inputStream) {
        inputStream = classLoader.getResourceAsStream("/" + resource);
      }

      if (null != inputStream) {
        return inputStream;
      }
    }
    return null;
  }


  /**
   * Attempt to load a class from a group of classloaders
   *
   * @param name        - the class to load
   * @param classLoader - the group of classloaders to examine
   * @return the class
   * @throws ClassNotFoundException - Remember the wisdom of Judge Smails: Well, the world needs ditch diggers, too.
   */
  Class<?> classForName(String name, ClassLoader classLoader) throws ClassNotFoundException {

    if (null != classLoader) {

      try {

        Class<?> c = Class.forName(name, true, classLoader);

        if (null != c) {
          return c;
        }

      } catch (ClassNotFoundException e) {
        // we'll ignore this until all classloaders fail to locate the class
      }

    }
    throw new ClassNotFoundException("Cannot find class: " + name);

  }


}
